package com.chatplus.application.controller.api;

import cn.dev33.satoken.annotation.SaIgnore;
import com.chatplus.application.client.pay.domain.response.InternalPayResponse;
import com.chatplus.application.common.constant.RedisPrefix;
import com.chatplus.application.common.exception.BadRequestException;
import com.chatplus.application.common.logging.SouthernQuietLogger;
import com.chatplus.application.common.logging.SouthernQuietLoggerFactory;
import com.chatplus.application.common.util.CreateCodeUtil;
import com.chatplus.application.common.util.MoneyUtils;
import com.chatplus.application.config.properties.AliPayProperties;
import com.chatplus.application.config.properties.WechatPayProperties;
import com.chatplus.application.domain.dto.OrderRemarkDto;
import com.chatplus.application.domain.entity.account.UserEntity;
import com.chatplus.application.domain.entity.basedata.ProductEntity;
import com.chatplus.application.domain.entity.orders.OrderEntity;
import com.chatplus.application.domain.request.PaymentQueryRequest;
import com.chatplus.application.domain.request.QrCodePayRequest;
import com.chatplus.application.domain.response.PaymentQueryResponse;
import com.chatplus.application.domain.response.QrCodePayResponse;
import com.chatplus.application.enumeration.OrderStatusEnum;
import com.chatplus.application.enumeration.PayChannelEnum;
import com.chatplus.application.service.account.UserService;
import com.chatplus.application.service.basedata.ProductService;
import com.chatplus.application.service.orders.OrderService;
import com.chatplus.application.service.pay.PayChannelServiceProvider;
import com.chatplus.application.service.pay.impl.PayProcessor;
import com.chatplus.application.web.basecontroller.BaseController;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * 支付API
 */
@Validated
@RestController
@RequestMapping("/api/payment")
@Tag(name = "支付API", description = "支付API")
public class PaymentApiController extends BaseController {
    private static final SouthernQuietLogger LOGGER = SouthernQuietLoggerFactory.getLogger(PaymentApiController.class);
    private final PayProcessor payProcessor;
    private final PayChannelServiceProvider payChannelServiceProvider;
    private final OrderService orderService;
    private final ProductService productService;
    private final UserService userService;
    private final AliPayProperties aliPayProperties;
    private final WechatPayProperties wechatPayProperties;
    private final RedissonClient redissonClient;

    @Autowired
    public PaymentApiController(PayProcessor payProcessor,
                                PayChannelServiceProvider payChannelServiceProvider,
                                OrderService orderService,
                                ProductService productService,
                                UserService userService,
                                AliPayProperties aliPayProperties,
                                WechatPayProperties wechatPayProperties,
                                RedissonClient redissonClient) {
        this.payProcessor = payProcessor;
        this.payChannelServiceProvider = payChannelServiceProvider;
        this.orderService = orderService;
        this.productService = productService;
        this.userService = userService;
        this.aliPayProperties = aliPayProperties;
        this.wechatPayProperties = wechatPayProperties;
        this.redissonClient = redissonClient;
    }

    @GetMapping("/payWays")
    @Operation(summary = "获取支付方法列表")
    @SaIgnore
    public Map<String, Map<String, String>> payWays() {
        Map<String, Map<String, String>> mapMap = new HashMap<>();
        if (aliPayProperties.isEnable()) {
            mapMap.put(PayChannelEnum.ALIPAY.getValue(), Map.of("name", PayChannelEnum.ALIPAY.getValue()));
        }
        if (wechatPayProperties.isEnable()) {
            mapMap.put(PayChannelEnum.WEI_XIN.getValue(), Map.of("name", PayChannelEnum.WEI_XIN.getValue()));
        }
        //  mapMap.put("hupi", Map.of("name", "wechat"));
        //  mapMap.put("payjs", Map.of("name", "wechat"));
        return mapMap;
    }

//    @GetMapping("/doPay")
//    @Operation(summary = "跳转支付")
//    @SaIgnore
//    public ModelAndView doPay(@RequestParam("pay_way") String payWay, @RequestParam("order_no") Long orderId) {
//        OrderEntity orderEntity = orderService.getById(orderId);
//        if (orderEntity == null) {
//            throw new BadRequestException("订单不存在");
//        }
//        PayChannelEnum payChannel = PayChannelEnum.get(payWay);
//        if (payChannel == null) {
//            throw new BadRequestException("支付方式不支持");
//        }
//        Long totalMoney = MoneyUtils.convertYuanToCent(orderEntity.getAmount(), 0);
//        InternalPayResponse internalPayResponse = payProcessor.payHandle(orderId, orderEntity.getUserId(), totalMoney, payChannel, orderEntity.getSubject());
//        orderEntity.setStatus(OrderStatusEnum.SCANNED);
//        orderService.updateById(orderEntity);
//        if (payChannel == PayChannelEnum.ALIPAY) {
//            return new ModelAndView(new RedirectView(internalPayResponse.getActionUrl()));
//        }
//        //TODO 其他支付
//        throw new BadRequestException("支付方式不支持");
//    }

    /**
     * 创建订单,返回二维码
     */
    @PostMapping("/qrcode")
    @Operation(summary = "二维码支付")
    public QrCodePayResponse qrcode(@RequestBody QrCodePayRequest qrCodePayRequest, HttpServletRequest request) {
        QrCodePayResponse qrCodePayResponse = new QrCodePayResponse();
        PayChannelEnum payChannel = qrCodePayRequest.getPayWay();
        if (payChannel == null) {
            throw new BadRequestException("支付方式不支持");
        }
        ProductEntity productEntity = productService.getById(qrCodePayRequest.getProductId());
        if (productEntity == null) {
            throw new BadRequestException("Product not found");
        }
        UserEntity userEntity = userService.getById(getLoginUser().getUserId());
        OrderEntity orderEntity = buildOrder(productEntity, userEntity, payChannel);
        orderService.save(orderEntity);
        String logo = payChannelServiceProvider.getPayChannelService(payChannel).getLogo();
        String doPayUrl;
        Long totalMoney = MoneyUtils.convertYuanToCent(orderEntity.getAmount(), 0);
        InternalPayResponse internalPayResponse = null;
        doPayUrl = switch (payChannel) {
            case ALIPAY, WEI_XIN -> {
                internalPayResponse = payProcessor.payHandle(orderEntity.getId(), orderEntity.getUserId(), totalMoney, payChannel, orderEntity.getSubject());
                yield internalPayResponse.getActionUrl();
            }
        };
        qrCodePayResponse.setOrderNo(orderEntity.getId());
        qrCodePayResponse.setImage(CreateCodeUtil.genQrcode(doPayUrl, 400, logo));
        qrCodePayResponse.setUrl(doPayUrl);
        return qrCodePayResponse;
    }

    /**
     * 创建订单,返回二维码
     */
    @PostMapping("/mobile")
    @Operation(summary = "二维码支付")
    public String mobile(@RequestBody QrCodePayRequest qrCodePayRequest, HttpServletRequest request) {
        QrCodePayResponse qrCodePayResponse = qrcode(qrCodePayRequest, request);
        if (qrCodePayResponse == null || StringUtils.isEmpty(qrCodePayResponse.getUrl())) {
            throw new BadRequestException("支付失败");
        }
        return qrCodePayResponse.getUrl();
    }

    @NotNull
    private static OrderEntity buildOrder(ProductEntity productEntity,
                                          UserEntity userEntity,
                                          PayChannelEnum payChannel) {
        OrderRemarkDto orderRemarkDto = new OrderRemarkDto();
        orderRemarkDto.setDays(productEntity.getDays());
        orderRemarkDto.setPower(productEntity.getPower());
        orderRemarkDto.setName(productEntity.getName());
        orderRemarkDto.setPrice(productEntity.getPrice());
        orderRemarkDto.setDiscount(productEntity.getDiscount());
        OrderEntity orderEntity = new OrderEntity();
        orderEntity.setAmount(productEntity.getPrice());
        orderEntity.setUsername(userEntity.getUsername());
        orderEntity.setUserId(userEntity.getId());
        orderEntity.setProductId(productEntity.getId());
        orderEntity.setSubject(productEntity.getName());
        orderEntity.setAmount(productEntity.getPrice().subtract(productEntity.getDiscount()));
        orderEntity.setStatus(OrderStatusEnum.NOT);
        orderEntity.setPayWay(payChannel);
        orderEntity.setRemark(orderRemarkDto);
        return orderEntity;
    }

    @PostMapping("/query")
    @Operation(summary = "支付查询")
    public PaymentQueryResponse query(@RequestBody PaymentQueryRequest paymentQueryRequest) {
        RBucket<PaymentQueryResponse> rBucket = redissonClient.getBucket(RedisPrefix.PAY_STATUS_PREFIX + paymentQueryRequest.getOrderNo());
        PaymentQueryResponse paymentQueryResponse = rBucket.isExists() ? rBucket.get() : null;
        if (paymentQueryResponse != null) {
            return paymentQueryResponse;
        }
        paymentQueryResponse = new PaymentQueryResponse();
        OrderEntity orderEntity = orderService.getById(paymentQueryRequest.getOrderNo());
        if (orderEntity == null) {
            throw new BadRequestException("订单不存在");
        }
        paymentQueryResponse.setStatus(orderEntity.getStatus());
        // 设置3秒缓存,支付成功会清空缓存
        rBucket.set(paymentQueryResponse, Duration.ofSeconds(3));
        return paymentQueryResponse;
    }

}
